import React, { useState, useEffect, useRef } from "react";
import { Form, Button, Input, Affix, Select, message, Space, Switch, Drawer, Row, Col, Modal, Radio, Checkbox } from "antd";
import { MinusCircleOutlined, PlusCircleOutlined, PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { useModelAssociateTypeAndMapping} from "@/components";
import cmdbres from "@/data/cmdbres";
import hcpiam from "@/data/hcpiam";
import request, {requestIAM} from '@/utils/request';
import regexpUtil from "@/utils/regexpUtil";
import hcpUtils from "@/utils/hcpUtils";
import { actionTypeOption, timeOptions, periodOptions, periodMinuteOptions, periodHourOptions, periodDayOptions } from './options';

const user = hcpUtils.getUser();
const CreateRelation = ({ history, info, visible, setVisible, onCreateFinish }) => {
    const [loading, setLoading] = useState(false);
    const [sourceModelKeyData, setSourceModelKeyData] = useState([]);
    const [targeteModelKeyData, setTargeteModelKeyData] = useState([]);
    const [conditionData, setConditionData] = useState(["="]);
	const [form] = Form.useForm();
    const [relationData, setRelationData] = useState([]);

    const [autoExecutionSwitch, setAutoExecutionSwitch] = useState(false);
    const [timeOptionsState, setTimeOptionsState] = useState(timeOptions);
    const [executionMethod, setExecutionMethod] = useState(actionTypeOption[0].value);
    const [periodOption, setPeriodOption] = useState(periodHourOptions);

    const getRelationData = async (params = { current: 1, pageSize: 99999999 }) => {
        try {
            const res = await request({
                ...cmdbres.queryAllModelAssociate,
                data: {
                    pageSize: params.pageSize,
                    pageNumber: params.current,
                },
            });
            if (res && res.data) {
                res.data.map((item, index) => {
                    item.key = item.id;
                    if(info && info.ruleId && item.id == info.moduleAssociateId) {
                        queryModelFilelds(item.srcModuleId, setSourceModelKeyData);
                        queryModelFilelds(item.destModuleId, setTargeteModelKeyData);
                    }
                });
                setRelationData(res.data);
            } else {
                setRelationData([]);
            }
        } catch (error) {
            console.log(error);
        } 
    };

    const queryModelFilelds = async (moduleId, setData) => {
        try {
            setData();
            let res = await request({ 
                ...cmdbres.queryModelPropertyList,
                data: {
                    queryFilter: {
                        EQ: {
                            cmModuleId: moduleId,
                        }
                    }
                }
            });
            if (res && res.code == 200) {
                setData(res.data);
            } else {
                setData([]);
            }
        } catch (error) {
            setData([]);
        }
    }

    useEffect(() => {
        if(visible) {
            getRelationData();
            if(info && info.ruleId) {
                const conditions = info.conditions?.map(item=>{
                    return {
                        srcModule: JSON.stringify({id: item.srcModulePropertyId, propertyKey: item.srcModuleAssociateKey}),
                        destModule: JSON.stringify({id: item.destModulePropertyId, propertyKey: item.destModuleAssociateKey}),
                        associateCondition: item.associateCondition
                    }
                })
                form.setFieldsValue({
                    ...info,
                    conditions
                })
                
            } else {
                form.setFieldsValue({
                    conditions: ['']
                })
            }
        }
    }, [visible]);
    const onSwitchChange = (value) => {
        setAutoExecutionSwitch(value);
        changeActionType({target: {value: actionTypeOption[0].value}});
        form.setFieldsValue({
            actionType: actionTypeOption[0].value,
            executionTime: undefined,
            repetitionCycle: undefined
        });
    }

    const changeActionType = (e) => {
        setExecutionMethod(e.target.value);
        form.setFieldsValue({
            periodUnit: '小时',
            periodValue: undefined
        });
        setPeriodOption(periodHourOptions)
    };

    const changeExecutionTime = (checkedValues) => {
        console.log(checkedValues.toString())
        const arr = JSON.parse(JSON.stringify(timeOptionsState));
        if (checkedValues?.length == 4) {
            arr.map(item => item.disabled = !checkedValues.includes(item.value));
        } else {
            arr.map(item => item.disabled = false);
        }
        setTimeOptionsState(arr);
    };

    const changePeriodType = (value) => {
        form.setFieldsValue({
            periodUnit: value,
            periodValue: undefined
        });
        if (value == '分') {
            setPeriodOption(periodMinuteOptions)
        }
        else if (value == '小时') {
            setPeriodOption(periodHourOptions)
        }
        else if (value == '天') {
            setPeriodOption(periodDayOptions)
        }
    }

	const onFinish = async (fieldsValue) => {
        setLoading(true);
        let param = Object.assign({}, fieldsValue, {author: user.staffName});
        param.conditions.map(item => {
            const srcModule = JSON.parse(item.srcModule);
            const destModule = JSON.parse(item.destModule);
            item.srcModulePropertyId = srcModule.id;
            item.srcModuleAssociateKey = srcModule.propertyKey;
            item.destModulePropertyId = destModule.id;
            item.destModuleAssociateKey = destModule.propertyKey;
            delete item.srcModule;
            delete item.destModule;  
        })
        let api = cmdbres.createModuleAssociateRule;
        if(info && info.ruleId) {
            api = cmdbres.editModuleAssociateRule(info.ruleId)
        } else {
            param.autoExecutionSwitch = param.autoExecutionSwitch ? 1 : 0
        };

        if(autoExecutionSwitch) {
            param.task = {actionType: param.actionType};
            if(param.actionType == '定时') {
                param.task.actionCron = '0 0 ' + param.executionTime?.toString() + ' ? * ' + param.repetitionCycle?.toString();
                delete param.executionTime;
                delete param.repetitionCycle;
            } else if(param.actionType == '周期') {
                param.task.periodUnit = param.periodUnit;
                param.task.periodValue = param.periodValue;
                delete param.periodUnit;
                delete param.periodValue;
            }
        }

		let res = await request({
			...api,
			data: param
		});
		setLoading(false);
		if (res && res.code == 200) {
			setVisible(false);
			message.success("保存成功！");
			if (typeof onCreateFinish == "function") onCreateFinish(res);
		}
	};

    const handleClose = () => {
        setVisible(false);
    }

    return (
        <Modal 
            title={info && info.ruleId?"编辑规则":"新建规则"}
            className="hcp-modal-md"
            onCancel={handleClose}
            visible={visible}
            footer={null}
            destroyOnClose
            afterClose={() => {
                form.resetFields();
            }}
        >
            <Form
                form={form}
                labelCol={{ span: 5}}
                wrapperCol={{ span: 17 }}
                name="basic"
                onFinish={onFinish}
            >
                <Form.Item 
                    label="规则名称" 
                    name="ruleName" 
                    rules={[{required: true,message: '请输入名称'}]}
                >
                    <Input placeholder="请输入名称" maxLength={64} />
                </Form.Item>
                 <Form.Item 
                    label="模型关联名称"
                    name="moduleAssociateId"
                    rules={[{required: true,message: '请选择模型关系'}]}
                    >
                    <Select
                        placeholder="请选择"
                        style={{ width: "100%", marginRight: 10 }}
                        onChange={(value, option) => {
                            form.resetFields(["conditions"]);
                            queryModelFilelds(option.relation.srcModuleId, setSourceModelKeyData);
                            queryModelFilelds(option.relation.destModuleId, setTargeteModelKeyData);
                        }}
                        showSearch
                    >
                        {
                            relationData?.map((item, index) => (
                                <Select.Option
                                    key={item.id}
                                    value={item.id}
                                    relation={item}
                                >
                                    {item.moduleAssociateName}
                                </Select.Option>
                            ))
                        }
                    </Select>
                </Form.Item>
                <Form.Item label="模型关联条件" required style={{marginBottom: 0}}>
                <Form.List 
                    name="conditions"
                    rules={[
                        {
                          validator: async (_, conditions) => {
                            if (!conditions || conditions.length < 1) {
                              return Promise.reject(new Error('至少要添加一条关联条件'));
                            }
                          },
                        },
                    ]}
                >
                    {(fields, { add, remove }, { errors }) => (
                        <>
                            {fields.map((field, index) => (
                            <Row key={index}>
                                <Col span={10}>
                                    <Form.Item
                                        name={[field.name, 'srcModule']}
                                        rules={[{required: true,message: '请选择源模型Key'}]}
                                        wrapperCol={24}
                                    >
                                        <Select
                                            placeholder="请选择源模型Key"
                                            style={{ width: "95%", marginRight: 10 }}
                                            loading={!sourceModelKeyData}
                                            showSearch
                                            optionFilterProp="children"
                                            getPopupContainer={(triggerNode) =>
                                                triggerNode.parentElement
                                            }
                                        >
                                            {
                                                sourceModelKeyData?.map((item, index) => {
                                                    let obj = {id: item.id, propertyKey: item.propertyKey}
                                                    return (
                                                        <Select.Option
                                                        key={item.id}
                                                        value={JSON.stringify(obj)}
                                                        title={`${item.propertyName}(${item.propertyKey})`}
                                                    >
                                                        {item.propertyName}({item.propertyKey})
                                                    </Select.Option>
                                                    )
                                                })
                                            }
                                        </Select>
                                    </Form.Item>
                                </Col>
                                <Col span={4}>
                                        <Form.Item
                                            name={[field.name, 'associateCondition']}
                                            rules={[{required: true,message: '请选择关系条件'}]}
                                            wrapperCol={22}
                                            initialValue={"="}
                                        >
                                            <Select
                                                placeholder="请选择"
                                                style={{ width: "90%", marginRight: 10 }}
                                            >
                                                {
                                                    conditionData?.map((item, index) => (
                                                        <Select.Option
                                                            key={index}
                                                            value={item}
                                                        >
                                                            {item}
                                                        </Select.Option>
                                                    ))
                                                }
                                            </Select>
                                        </Form.Item>
                                    </Col>
                                <Col span={10}>
                                    <Form.Item
                                        name={[field.name, 'destModule']}
                                        rules={[{required: true,message: '请选择目标模型Key'}]}
                                        wrapperCol={22}
                                    >
                                        <Select
                                            placeholder="请选择目标模型Key"
                                            style={{ width: "100%", marginRight: 10 }}
                                            loading={!targeteModelKeyData}
                                            showSearch
                                            optionFilterProp="children"
                                            getPopupContainer={(triggerNode) =>
                                                triggerNode.parentElement
                                            }
                                        >
                                            {
                                                targeteModelKeyData?.map((item, index) => {
                                                    let obj = {id: item.id, propertyKey: item.propertyKey}
                                                    return (
                                                        <Select.Option
                                                        key={item.id}
                                                        value={JSON.stringify(obj)}
                                                        title={`${item.propertyName}(${item.propertyKey})`}
                                                    >
                                                        {item.propertyName}({item.propertyKey})
                                                    </Select.Option>
                                                    )
                                                })
                                            }
                                        </Select>
                                    </Form.Item>
                                </Col>
                                {
                                    index > 0 &&
                                    <Col span={2} className="text-center">
                                        <Button
                                            type="link"
                                            onClick={() => {remove(field.name)}}
                                        >
                                            删除
                                        </Button>
                                    </Col>
                                }
                            </Row>
                            ))}
                           {
                            fields.length == 0 ? 
                            <Form.Item>
                                <Button
                                    type="dashed"
                                    onClick={() => add()}
                                    style={{ width: '60%' }}
                                    icon={<PlusOutlined />}
                                >
                                    添加
                                </Button>
                                <Form.ErrorList errors={errors} />
                            </Form.Item>: null
                           }
                        </>
                    )}
                </Form.List>
                </Form.Item>
                {
                    !(info && info.ruleId) &&
                    <Form.Item
                        label="自动执行"
                        name="autoExecutionSwitch"
                        required
                        initialValue={false}
                    >
                        <Switch
                            checkedChildren="ON"
                            unCheckedChildren="OFF"
                            onChange={onSwitchChange}
                        />
                    </Form.Item>
                }
                {
                    autoExecutionSwitch && 
                    <>
                        <Form.Item 
                            label="执行方式" 
                            name='actionType'
                            rules={[
                                { required: true, message: '请选择执行方式' },
                            ]}
                        >
                            <Radio.Group onChange={changeActionType}>
                                {actionTypeOption.map(item=> {
                                    return (
                                        <Radio key={item.value} value={item.value}>{item.label}</Radio>
                                    )
                                })}
                            </Radio.Group>
                        </Form.Item>
                        {
                            executionMethod == '定时' &&
                            <>
                                <Form.Item label="执行时间" name='executionTime'
                                    rules={[
                                        { required: true, message: '请选择执行时间' },
                                    ]}>
                                    <Checkbox.Group 
                                        options={timeOptionsState} 
                                        onChange={changeExecutionTime} 
                                        style={{ width: 550 }}
                                    >
                                    </Checkbox.Group>
                                </Form.Item>
                                <Form.Item label="重复周期" name='repetitionCycle'
                                    rules={[
                                        { required: true, message: '请选择重复周期' },
                                    ]}>
                                    <Checkbox.Group options={periodOptions}>
                                    </Checkbox.Group>
                                </Form.Item>
                            </>
                        }
                        {
                            executionMethod == '周期' &&
                            <>
                                <Form.Item label="重复周期单位" name='periodUnit'
                                    rules={[
                                        { required: true, message: '请选择重复周期单位' },
                                    ]}>
        
                                    <Select 
                                        style={{ width: 300 }} 
                                        defaultValue={'小时'} 
                                        onChange={changePeriodType}
                                    >
                                        <Select.Option value={'天'}>天</Select.Option>
                                        <Select.Option value={'小时'}>小时</Select.Option>
                                        <Select.Option value={'分'}>分</Select.Option>
                                    </Select>
                                    <Row style={{ marginTop: 10 }}>
                                        <ExclamationCircleOutlined 
                                            style={{ color: '#439FE1', marginTop: 3, marginRight: 3 }} 
                                        />
                                        <span style={{ color: '#999999' }}>
                                            任务未完成时不自动执行下次任务
                                        </span>
                                    </Row>
                                </Form.Item>
                                <Form.Item label="重复周期值" name='periodValue'
                                    rules={[
                                        { required: true, message: '请选择重复周期值' },
                                    ]}>
        
                                    <Radio.Group>
                                        {
                                            periodOption?.map((item, index) => {
                                                return <Radio key={item.value} value={item.value}>{item.label}</Radio>
                                            })
                                        }
                                    </Radio.Group>
        
                                </Form.Item>
                            </>
                        }
                    </>
                }
                <Form.Item
                    label="描述"
                    name="description"
                    key="description"
                >
                    <Input.TextArea />
                </Form.Item>
                <div className="hcp-modal-body-footer">
                    <Form.Item wrapperCol={{ span: 24 }}>
                        <Button onClick={handleClose}>取消</Button>
                        <Button type="primary" htmlType="submit" loading={loading}>确定</Button>
                    </Form.Item>
                </div>
            </Form>
        </Modal>
    );
};

export default CreateRelation;
